package com.xoa.dev.muping.sso;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xoa.dao.common.SysParaMapper;
import com.xoa.dao.sys.SysInterfaceMapper;
import com.xoa.dao.thirdSysConfig.ThirdSysConfigMapper;
import com.xoa.dao.users.OrgManageMapper;
import com.xoa.dao.users.UserFunctionMapper;
import com.xoa.dao.users.UsersMapper;
import com.xoa.dev.muping.util.RsaSignatureUtil;
import com.xoa.dev.muping.util.SignatureUtil;
import com.xoa.model.common.SysPara;
import com.xoa.model.common.Syslog;
import com.xoa.model.sys.InterfaceModel;
import com.xoa.model.thirdSysConfig.ThirdSysConfigExample;
import com.xoa.model.thirdSysConfig.ThirdSysConfigWithBLOBs;
import com.xoa.model.users.OrgManage;
import com.xoa.model.users.UserOnline;
import com.xoa.model.users.Users;
import com.xoa.service.sys.SysLogService;
import com.xoa.service.users.UsersService;
import com.xoa.util.CookiesUtil;
import com.xoa.util.DateFormatUtils;
import com.xoa.util.LoginState;
import com.xoa.util.ToJson;
import com.xoa.util.common.StringUtils;
import com.xoa.util.common.session.SessionUtils;
import com.xoa.util.dataSource.ContextHolder;
import com.xoa.util.http.HttpClientUtil;
import com.xoa.util.sso.CASUtils;
import org.apache.commons.collections4.map.HashedMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.text.ParseException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("mp")
public class SSOLogin {


    @Autowired
    UserFunctionMapper userFunctionMapper;

    @Autowired
    private SysInterfaceMapper sysInterfaceMapper;

    @Autowired
    private SysLogService sysLogService;

    @Autowired
    private UsersMapper usersMapper;
    @Autowired
    private OrgManageMapper orgManageMapper;
    @Autowired
    private UsersService usersService;
    @Autowired
    private SysParaMapper sysParaMapper;
    @Autowired
    private ThirdSysConfigMapper thirdSysConfigMapper;

    public static Map<String, Object> userCountMap = new HashedMap();

    private ThirdSysConfigWithBLOBs thirdSysConfig = new ThirdSysConfigWithBLOBs();
    private String TOKEN = "";
    private String REFRESH_TOKEN = "";
    // accessToken 生成时间（两个小时有效期
    private Long Token_TimeLimit = new Date().getTime();



    public Map<String, String> getParameterMap() {
        Map<String, String> parameterMap = new HashMap<>();

        ThirdSysConfigExample thirdSysConfigExample = new ThirdSysConfigExample();
        ThirdSysConfigExample.Criteria criteria = thirdSysConfigExample.createCriteria();
        criteria.andSysNameEqualTo("牟平JIS单点系统");
        List<ThirdSysConfigWithBLOBs> thirdSysConfigs = thirdSysConfigMapper.selectByExampleWithBLOBs(thirdSysConfigExample);
        if(thirdSysConfigs!=null&&thirdSysConfigs.size()>0){
            thirdSysConfig = thirdSysConfigs.get(0);
        }

        // 应用唯一标识（JMAS平台获取）
        parameterMap.put("app_id", thirdSysConfig.getPara1());

        // 版本号(格式:x.x, 例如:1.0)
        parameterMap.put("version", thirdSysConfig.getPara4());

        // 编码格式, 默认UTF-8
        String charset = "UTF-8";
        parameterMap.put("charset", charset);

        // 时间戳，毫秒为单位
        parameterMap.put("timestamp", String.valueOf(System.currentTimeMillis()));

        // 来源 0：PC；1：APP；2：支付宝；3：微信
        parameterMap.put("origin", "0");

        return parameterMap;
    }


    // 获取令牌接口
    public JSONObject getToken(String ticket) {
        if (!StringUtils.checkNull(ticket)) {
            Map<String, String> parameterMap = getParameterMap();

            // 接口唯一标识（JMAS平台获取）
            parameterMap.put("interface_id", "ticketvalidate");

            // 三方接口的参数，json格式：{"键":"值", "键":"值"}
            Map<String, String> paramMap = new HashMap<>(16);
            paramMap.put("servicename", "ticketValidate");
            Map<String,String> params = new HashMap<>();
            params.put("ticket",ticket);
            paramMap.put("params", JSON.toJSONString(params));
            /*if (!StringUtils.checkNull(TOKEN)) {
                paramMap.put("token", TOKEN);
                paramMap.put("refreshtoken", "刷新token");
            }*/
            paramMap.put("app_id", thirdSysConfig.getPara1());
            String bizContent = JSON.toJSONString(paramMap);
            parameterMap.put("biz_content", bizContent);

            // 签名
            parameterMap.put("sign", createSign(parameterMap, "utf-8"));
            String rsaResult = HttpClientUtil.doGsonPost(thirdSysConfig.getPara5(), parameterMap, "utf-8");

            JSONObject resultJson = JSONObject.parseObject(rsaResult);
            String success = resultJson.getString("success");
            if (!StringUtils.checkNull(success) && "true".equals(success)) {
                JSONObject res = getSecretData(resultJson.getString("data"));
                return  JSONObject.parseObject(res.getString("data"));
            }

        }
        return null;
    }

    // 获取用户信息接口
    public JSONObject getUserInfo(String token) {
        JSONObject result = new JSONObject();
        Map<String, String> parameterMap = getParameterMap();
        // 接口唯一标识（JMAS平台获取）
        parameterMap.put("interface_id", "findoutsideuserbytoken");

        // biz_content参数
        Map<String, String> paramMap = new HashMap<>(16);
        paramMap.put("app_id", thirdSysConfig.getPara1());
        paramMap.put("servicename", "findOutsideUserByToken");
        paramMap.put("params", "{\"token\":\"" + token + "\"}");

        String bizContent = JSON.toJSONString(paramMap);
        parameterMap.put("biz_content", bizContent);

        // sign
        parameterMap.put("sign", createSign(parameterMap, "utf-8"));

        String rsaResult = HttpClientUtil.doGsonPost(thirdSysConfig.getPara5(), parameterMap, "utf-8");
        JSONObject jsonObject = JSONObject.parseObject(rsaResult);
        if("true".equals(jsonObject.getString("success"))){
            JSONObject resultJson = getSecretData(jsonObject.getString("data"));

            if (resultJson!=null) {
                String retcode = resultJson.getString("retcode");
                if (!StringUtils.checkNull(retcode) && "000000".equals(retcode)) {
                    result = JSONObject.parseObject(resultJson.getString("data"));
                }
            }
        }

        return result;
    }

    // 获取法人信息接口
    public JSONObject getFaUserInfo(String token) {
        JSONObject result = new JSONObject();
        Map<String, String> parameterMap = getParameterMap();
        // 接口唯一标识（JMAS平台获取）
        parameterMap.put("interface_id", "findcorporationbytoken ");

        // biz_content参数
        Map<String, String> paramMap = new HashMap<>(16);
        paramMap.put("app_id", thirdSysConfig.getPara1());
        paramMap.put("servicename", "findCorporationByToken");
        paramMap.put("params", "{\"token\":\"" + token + "\"}");

        String bizContent = JSON.toJSONString(paramMap);
        parameterMap.put("biz_content", bizContent);

        // sign
        parameterMap.put("sign", createSign(parameterMap, "utf-8"));

        String rsaResult = HttpClientUtil.doGsonPost(thirdSysConfig.getPara5(), parameterMap, "utf-8");
        JSONObject jsonObject = JSONObject.parseObject(rsaResult);
        if("true".equals(jsonObject.getString("success"))){
            JSONObject resultJson = getSecretData(jsonObject.getString("data"));

            if (resultJson!=null) {
                String retcode = resultJson.getString("retcode");
                if (!StringUtils.checkNull(retcode) && "000000".equals(retcode)) {
                    result = JSONObject.parseObject(resultJson.getString("data"));
                }
            }
        }

        return result;
    }


    // 登录接口
    @ResponseBody
    @RequestMapping("ssoLogin")
    public String ssoLogin(String ticket, HttpServletRequest request, HttpServletResponse response, String loginId) {
        String usertype = "";
        String token = "";
        if(!StringUtils.checkNull(ticket)){
            JSONObject jsonObjectToken = getToken(ticket);
            if(jsonObjectToken==null||StringUtils.checkNull(jsonObjectToken.getString("token"))){
                return "token is null";
            }
            usertype =jsonObjectToken.getString("usertype");
            token=jsonObjectToken.getString("token");
        }
        JSONObject userInfo = null;
        if(usertype.equals("1")){
            userInfo = getUserInfo(token);
        } else if(usertype.equals("2")) {
            userInfo = getFaUserInfo(token);
        }
        if (userInfo != null) {
            String cardid = userInfo.getString("papersnumber");
            String mobile = userInfo.getString("mobile");
            String name = userInfo.getString("name");
            Users userByIdNumber = usersMapper.getUserByIdNumber(cardid);
            try {
                // 个人登录
                if(usertype.equals("1")){
                    // 根据身份证号查询 登录
                    if (userByIdNumber != null) {
                        ssoLoginEnter(request, response, loginId, userByIdNumber.getByname(), "/main");
                    } else {
                        // 如果身份证号查询不到 根据姓名和手机号查询登录
                        Users user = usersMapper.selectByPhoneAndName(name, mobile);
                        if (user != null) {
                            ssoLoginEnter(request, response, loginId, user.getByname(), "/main");
                        } else{
                            // 第三种根据手机号当作登录名查询信息进行登录
                            user = usersMapper.getUsersBybyname(mobile);
                            if(user!=null)
                                ssoLoginEnter(request, response, loginId, mobile, "/main");
                        }
                    }
                } else { // 法人登录
                    String cornumber = userInfo.getString("cornumber");
                    Users user = usersMapper.getUsersBybyname(cornumber);
                    if(user!=null)
                        ssoLoginEnter(request, response, loginId, mobile, "/main");
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return "";
    }


    // 登录跳转接口
    public ToJson<Users> ssoLoginEnter(HttpServletRequest request, HttpServletResponse response, String loginId, String username, String OAtargeturl) throws Exception {
        response.addHeader("Access-Control-Allow-Origin", "*");
        response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
        response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
        response.addHeader("Access-Control-Max-Age", "1800");//30 min

        String serverName = request.getServerName();
        String targetUrl = request.getScheme() + "://" + serverName;
        int port = request.getServerPort();
        if (80 != port && 443 != port) {//默认端口，不加在跳转路径下
            targetUrl += ":" + request.getServerPort();
        }
        CASUtils casUtils = new CASUtils();
        HttpSession session = request.getSession();

        //OAtargeturl = StringUtils.checkNull(OAtargeturl) ? "/main":OAtargeturl;
        if (casUtils.isLogin(session)) {
            response.sendRedirect(targetUrl + OAtargeturl);
        } else {

            CookiesUtil.setCookie(response, "redisSessionId", request.getSession().getId());
            Cookie redisSessionCookie = new Cookie("redisSessionId", request.getSession().getId());
            if (StringUtils.checkNull(loginId)) {
                List<OrgManage> org = orgManageMapper.queryId();
                if (org != null && org.size() > 0) {
                    loginId = org.get(0).getOid().toString().trim();
                }
            }


            ToJson<Users> json = new ToJson<Users>(0, null);
            if (StringUtils.checkNull(username)) {
                json.setFlag(1);
                json.setCode(LoginState.LOGINPASSWORDERR);
                json.setMsg("用户名或用户不存在");
                return json;
            }
            ContextHolder.setConsumerType("xoa" + loginId);
            Users user = usersMapper.selectUserAllInfoByName(username);
            if (user == null) {
               /* request.getSession().setAttribute("message", "errOne");
                json.setMsg("用户名或用户不存在");
                json.setCode(LoginState.LOGINPASSWORDERR);
                json.setFlag(1);*/
                response.sendRedirect(targetUrl + "/defaultIndexErrCas");
                return json;

            }

            List<SysPara> list = sysParaMapper.selectAll();
            String pd = "";
            String xts = "";
            String cz = "";
            for (SysPara sysPara : list) {
                if ("SEC_RETRY_BAN".equals(sysPara.getParaName())) {
                    pd = sysPara.getParaValue();
                }
                if ("SEC_RETRY_TIMES".equals(sysPara.getParaName())) {
                    xts = sysPara.getParaValue();
                }
                if ("SEC_BAN_TIME".equals(sysPara.getParaName())) {
                    cz = sysPara.getParaValue();
                }
            }


            //获取当前用户的登录日志
            ToJson<Syslog> modifyPwdLog = sysLogService.getLoginLog(request);
            if (user.getLastVisitTime() != null) {
                user.setLastVisitTime(new Date());
                usersService.updateLoginTime(user);
            } else {
                //判断他的size小于等于1，因为在查用户user信息时写入log日志的，因此第一次登录size为1
                if (modifyPwdLog.getObj() == null || modifyPwdLog.getObj().size() <= 1) {
                    json.setCode("FirstLogin");
                } else {
                    user.setLastVisitTime(new Date());
                    usersService.updateLoginTime(user);
                }
            }

            if (StringUtils.checkNull(loginId)) {
                List<OrgManage> org = orgManageMapper.queryId();
                if (org != null && org.size() > 0) {
                    loginId = org.get(0).getOid().toString().trim();
                }
            }
            user.setCompanyId(loginId);
            //判断用户头像
            if (StringUtils.checkNull(user.getAvatar())) {
                if (!StringUtils.checkNull(user.getSex())) {
                    user.setAvatar(user.getSex());
                } else {
                    user.setAvatar("0");
                }

            } else {
                if (user.getAvatar().equals("0") || user.getAvatar().equals("1")) {
                    if (!StringUtils.checkNull(user.getSex())) {
                        user.setAvatar(user.getSex());
                    } else {
                        user.setAvatar("0");
                    }
                } else {
                    //判断用户头像是否找得到
                    String classpath = this.getClass().getResource("/").getPath();
                    String webappRoot = classpath.replaceAll("WEB-INF/classes/", "ui/img/user/");
                    File file_avtor = new File(webappRoot + user.getAvatar());
                    if (!file_avtor.exists()) {
                        user.setAvatar(user.getSex());
                    }
                }
            }
            json.setObject(user);
            json.setFlag(0);

            //通过userId查询用户是否存在于静态map中
            UserOnline userOnline = (UserOnline) userCountMap.get(user.getUserId());
            //如果不存在
            if (userOnline == null) {
                //声明一个新的用户在线数据
                UserOnline userOnlineInfo = new UserOnline();
                try {
                    String format = DateFormatUtils.formatDate(new Date());
                    Integer nowTime = DateFormatUtils.getNowDateTime(format);
                    userOnlineInfo.setClient((byte) 2);
                    userOnlineInfo.setPCtime(nowTime);
                    userOnlineInfo.setPCsid(request.getSession().getId());
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            } else {//如果存在
                if (!userOnline.getPCsid().equals("")) {
                    try {
                        String format = DateFormatUtils.formatDate(new Date());
                        Integer nowTime = DateFormatUtils.getNowDateTime(format);
                        userOnline.setPCtime(nowTime);
                        userCountMap.put(user.getUserId(), userOnline);
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                } else {
                    try {
                        String format = DateFormatUtils.formatDate(new Date());
                        Integer nowTime = DateFormatUtils.getNowDateTime(format);
                        userOnline.setPCtime(nowTime);
                        userOnline.setPCsid(request.getSession().getId());
                        userCountMap.put(user.getUserId(), userOnline);
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                }
            }

            Map<String, Object> params = new HashMap<String, Object>();
            params.put("paraName", "IM_WINDOW_CAPTION");
            params.put("paraValue", user.getPara().getParaValue());
            params.put("loginDateSouse", loginId);//组织id
            params.put("LOCALE_SESSION_ATTRIBUTE_NAME", "zh_CN");//语言


            String functionIdStr = userFunctionMapper.getUserFuncIdStr(user.getUserId());
            params.put("functionIdStr", functionIdStr);

            List<InterfaceModel> interfaceModels = sysInterfaceMapper.getInterfaceInfo();
            if (0 == user.getTheme() || null == user.getTheme()) {
                user.setTheme((byte) Integer.parseInt(interfaceModels.get(0).getTheme()));
            }

            String theme = "theme" + user.getTheme();
            params.put("InterfaceModel", theme);
            params.put("uid", user.getUid());
            params.put("userId", user.getUserId());
            params.put("userPriv", user.getUserPriv());
            SessionUtils.putSession(request.getSession(), params, redisSessionCookie);
            SessionUtils.putSession(request.getSession(), user, redisSessionCookie);
            response.sendRedirect(targetUrl + OAtargeturl);
        }
        return null;
    }


    // 创建sign
    public String createSign(Map<String, String> map, String charset) {
        // 获取sign
        return SignatureUtil.rsaSign(map, thirdSysConfig.getPara0(), charset, "RSA");
    }

    /**
     * @param secret
     * @return
     * @throws Exception
     * @Description:解密网关返回的密文
     * @date 2019年12月19日下午1:50:00
     */
    public JSONObject getSecretData(String secret) {
        JSONObject jsonObject = new JSONObject();
        try {

            String decrypt = RsaSignatureUtil.decrypt(secret, RsaSignatureUtil.getPrivateKey( thirdSysConfig.getPara0()));

            // 判断是否开头和结尾是 “ 如果是的话 删除掉
            if(decrypt.indexOf("\"")==0){
                decrypt = decrypt.substring(1);
            }
            if(decrypt.lastIndexOf("\"")==decrypt.length()-1){
                decrypt = decrypt.substring(0,decrypt.length()-1);
            }
            System.out.println(decrypt);
            decrypt = decrypt.replace("\\\"","\"");
            if(decrypt.contains("\\\\\"")){
                decrypt = decrypt.replace("\\\\\"","\\\"");
            }
            System.out.println(decrypt);
            jsonObject = JSONObject.parseObject(decrypt);

        } catch (Exception e) {
            e.printStackTrace();
        }
        return jsonObject;
    }
}
